package com.dksoftware.combo;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;

public class ComboServlet extends HttpServlet {

    /**
     *
     */
    private static final long serialVersionUID = -708497924441068698L;

    private static Properties properties = new Properties();

    /*private static final class LoadedFile {
		private byte[] fileData = new byte[0];
		private boolean isGzipped = false;
	}*/

    /**
     * the parameters we send to the servlet
     */
    enum parameters {
        type, theme, resources, v
    }

    @Override
	public void init() throws ServletException {
		try {
		    //TODO: allow external properties from CLASSPATH
			properties.load(getServletContext().getResourceAsStream("/WEB-INF/config.properties"));
		} catch (IOException e) {
			throw new ServletException("Error loading /WEB-INF/config.properties");
		}
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // send 501 error response code
        response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	// 1. Identify request type css/javascript, collect all request info required into RequestDetails object
    	// 2. Get collection of files for commons, theme and explicitly specified via 'resources' URL parameter
    	// 3. Check if request or files were modified
    	// 4. Get files as bytes, minify, compress
    	// 5. Set response headers

    	// parse "query string"
    	// TODO: create request details object
    	Map<String,String> qsParams = parseQueryString(request, response);
    	String type = qsParams.get("type");
    	String resources = qsParams.get("resources");
    	boolean versionized = qsParams.get("v") != null;

    }

    // test it
    static Map<String,String> parseQueryString(HttpServletRequest request, HttpServletResponse response) throws IOException {
    	Map<String,String> qsParams = getQSParams(request.getRequestURL().toString());
    	if (qsParams.isEmpty()) {
			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No query string to parse");
		}
    	return qsParams;
    }

    /**
     * The method returns ordered set of files specified by 'resources' URL parameter. Return set to
     * avoid file duplicates.
     *
     * @param resources
     *            - an query string comma separated parameters to parse
     * @return set of resources files, never null
     * @throws UnsupportedEncodingException
     * @throws MalformedURLException
     */
    Set<File> getResourcesFiles(String resources) throws MalformedURLException, UnsupportedEncodingException {
        Set<File> linkedFileSet = new LinkedHashSet<File>();
        if (resources == null) {
            return linkedFileSet; // return empty set
        }
        String params[] = resources.split(",");
        for (String param : params) {
            String realPath = getServletContext().getRealPath(param);
            if (realPath != null) {
                linkedFileSet.add(getLocalFile(realPath));
            }
        }
        return linkedFileSet;
    }

    /**
     * The method receives a path of local the file to return.
     *
     * @param path
     *            - the path of the file
     * @return File object, never null
     * @throws MalformedURLException
     * @throws UnsupportedEncodingException
     */
    static File getLocalFile(String path) throws MalformedURLException, UnsupportedEncodingException {
        return FileUtils.getFile(path);
    }

    /**
     * The method gets local file path (<tt>/tmp/somefile.txt</tt>) and transforms it into local URL
     * (<tt>file:///tmp/somefile.txt</tt>).
     *
     * @param path
     *            - the file path to transform
     * @return URL, never null
     * @throws MalformedURLException
     * @throws UnsupportedEncodingException
     */
    static URL getLocalFileURL(String path) throws MalformedURLException, UnsupportedEncodingException {
        return new URL("file://" + path);
    }

    /**
     * Most proxies, most notably Squid up through version 3.0, do not cache resources with a "?" in
     * their URL even if a Cache-control: public header is present in the response. To enable proxy
     * caching for these resources, remove query strings from references to static resources, and
     * instead encode the parameters into the file names themselves.
     *
     * @see http://code.google.com/speed/page-speed/docs/caching.html
     *
     * @param requestURL
     *            - the request URL
     *
     * @return query string parameters Map, never null
     */
    static Map<String, String> getQSParams(String requestURL) {
        Map<String, String> paramMap = new HashMap<String, String>();
        if (requestURL == null) {
            return paramMap;
        }
        int i = 0;
        for (String param : requestURL.split("&")) {
            if (i > 0) {
                String key = param.split("=")[0];
                String value = param.split("=")[1];
                paramMap.put(key, value);
            }
            i++;
        }
        return paramMap;
    }

    @Override
	public String getServletInfo() {
		return "Combinatorius servlet by Denis Kiriusin (deniskir@gmail.com)";
	}

}
